
with Ada.Text_IO; use Ada.Text_IO; 
with Ada.Command_Line; use Ada.Command_Line;
with Interfaces; use Interfaces;

-- https://leetcode.com/problems/gray-code/
procedure leet89_greycode is
    subtype byte is unsigned_8; -- challenge only demands up to 16
    package byte_IO is new Ada.Text_IO.Modular_IO (byte);
    type vector is array (positive range<>) of byte;

    procedure print(v : in vector) is 
    begin
        for element of v loop
            put(element'image & " ");
        end loop;
    end print;

    function bin2grey (x : in byte) return byte is
    begin 
        return x xor (shift_right(x, 1));
    end bin2grey;

    function greycode(n : in natural) return vector is 
        output : vector(1 .. 2*n) := (others => 0);
        index : positive := 1;
    begin 
        for i in 0 .. 2*n-1 loop -- run 2n times but start from 0
            output(index) := bin2grey(byte(i));
            index := index + 1;
        end loop;
        return output;
    end greycode;

    procedure main is 
        input : natural := natural'value(argument(1));
    begin 
        if input < 1 or input > 16 then
            put_line("Exited. Parameter is outside constraints.");
        else
            print(greycode(input));
        end if;
        null;
    end main;

begin
    put_line("This is leetcode math challenge #80 - Grey Code");
    if argument_count < 1 then
        put_line("usage: <program name> <# of bits>");
    end if;
    main;
end leet89_greycode;


